package is.sclab.datastore.entitygroup;

import is.sclab.service.LowLevelAPI;

import java.util.ArrayList;
import java.util.List;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Text;
import com.google.appengine.api.datastore.Transaction;

public class LowLevelAPIImpl implements LowLevelAPI{

    DatastoreService DatastoreService;
    
    protected void service(){
    	if(DatastoreService == null){
        	DatastoreService = DatastoreServiceFactory.getDatastoreService();
        }
    }
    
    //Create
    public void SaveParent(Parent ParentEntity){
    	service();
    	Entity RootEntity = new Entity(ParentEntity.getKey());
        RootEntity.setProperty("Value1",ParentEntity.getValue());
        Transaction tx = DatastoreService.beginTransaction();
        try{
        	DatastoreService.put(tx,RootEntity);
        	tx.commit();
        }finally{
        	if(tx.isActive()){
        		tx.rollback();
        	}
        }
    }
    
    public void SaveChild(Child ChildEntity){
    	service();
    	Entity Entity = new Entity(ChildEntity.getKey());
    	Entity.setProperty("Value1",ChildEntity.getValue1());
    	Entity.setProperty("Value2",ChildEntity.getValue2());
    	Transaction tx = DatastoreService.beginTransaction();
    	try{
    		DatastoreService.put(tx,Entity);
    		tx.commit();
    	}finally{
    		if(tx.isActive()){
    			tx.rollback();
    		}
    	}
    }
    
    //Read
    public List<Parent> getParentList(){
    	service();
    	Query ParentQuery = new Query("Parent");
        Iterable<Entity> ParentIter = DatastoreService.prepare(ParentQuery).asIterable();
        ArrayList<Parent> ParentList= new ArrayList<Parent>();
        for (Entity ParentEntity : ParentIter) {
        	ParentList.add(new Parent.Builder(ParentEntity.getKey()).Value((String)ParentEntity.getProperty("Value1")).Build());
        }
        return ParentList;
    }
    
    public List<Child> getChildList(Key parentkey){
    	service();
    	ArrayList<Child> ChildList= new ArrayList<Child>();
    	Query ChildQuery = new Query("Child",parentkey);
    	Iterable<Entity> ChildIter = DatastoreService.prepare(ChildQuery).asIterable();
    	for(Entity ChildEntity:ChildIter){
    		ChildList.add(new Child.Builder(ChildEntity.getKey()).Value1((String)ChildEntity.getProperty("Value1")).Value2((Text)ChildEntity.getProperty("Value2")).Build());
    	}
    	return ChildList;
    }
    
    //UpDate
    public void UpDateParent(Parent ParentEntity){
    	service();
    	try{
    		Entity RootEntity = DatastoreService.get(ParentEntity.getKey());
    		RootEntity.setProperty("Value",ParentEntity.getValue());
    		DatastoreService.put(RootEntity);
    	}catch (EntityNotFoundException e) {
    		System.out.println("要素がありません");
    	}
    }
    
    public void UpDateChild(Child ChildEntity){
    	service();
    	try{
    		Entity Entity = DatastoreService.get(ChildEntity.getKey());
    		Entity.setProperty("Value1",ChildEntity.getValue1());
    		Entity.setProperty("Value2",ChildEntity.getValue2());
    		DatastoreService.put(Entity);
    	}catch (EntityNotFoundException e) {
    		System.out.println("要素がありません");
    	}
    }
    
    public void update(Key[] keys,String Value){
    	service();
    	Transaction tx = DatastoreService.beginTransaction();
    	try{
    		for(int i=0;i<keys.length;i++){
    			Entity entity = DatastoreService.get(keys[i]);
    			entity.setProperty("Value1",Value);
    			DatastoreService.put(tx, entity);
    		}
    		tx.commit();
    	}catch (EntityNotFoundException e) {
    		System.out.println("要素がありません");
		}finally{
			if(tx.isActive()){
				tx.rollback();
			}
		}
    }
    
    //Delete
    public void DeleteEntity(Key Key){
    	service();
    	DatastoreService.delete(Key);
    }
    
    public void Delete(Key[] keys){
    	service();
    	Transaction tx = DatastoreService.beginTransaction();
    	try{
    		DatastoreService.delete(tx,keys);
    		tx.commit();
    	}catch (IllegalStateException e) {
    		System.out.println("要素がありません");
		}finally{
			if(tx.isActive()){
				tx.rollback();
			}
		}
    }
}
